//
//  FilterManager.swift
//  Automobile
//
//  Created by erkebulan elzhan on 7/22/20.
//  Copyright © 2020 erkebulan elzhan. All rights reserved.


import Foundation


/// Utility for loading adverts with Filter
final class FilterManager {
    
    
    /// Loading Posts with filter
    /// - Parameters:
    ///   - filter: Filter struct contains all filters
    ///   - request: pagination request, which is can be null, if there is no next page, or if that is first page
    ///   - completion: returns array of posts or Error
    public func getPosts(filter: Filter, request: URLRequest?=nil, completion: @escaping (Result<Response<[Post]>, RequestError>) -> Void) {
        
        let backendService = Backend()
        
        // MARK:- TODO: put here variable

        var postRequest: URLRequest!
        
        if (request != nil) {
            
            // pagination
            postRequest = request!
            
        } else {
            
            // first page request
            let _request = Request(base: .advert, parameters: self.createFilter(filter))
            
            postRequest = URLRequest(url: _request.getUrl(path: "adverts/all/"))
        }

        backendService.fetchFromBackend(for: Response<[Post]>.self, request: postRequest, statusCode: 200) { (result) in
            completion(result)
        }
    }
    
    /// Converting Filter Struct to [Key:Value] parameters dictionary
    /// - Parameter filter: Filter
    /// - Returns: URLQueryItem's array
    private func createFilter (_ filter: Filter) -> [URLQueryItem] {
        
        let keys: [String] = [
            "mark_ext", "model_ext", "generation_ext", "year_begin", "year_end",
            "price_begin", "price_end",
            "transmission", "body", "engine", "color", "drive_type", "rule_type", "condition_type", "city",
            "power_begin", "power_end", "mileage_begin", "mileage_end", "engine_volume_begin", "engine_volume_end",
             "exchange", "options_single_fields", "options_choice_fields", "options_multiple_fields"
        ]
        
        // generations
        var gens: [String] = []
        
        // getting all generations from filter
        for model in filter.filterCar.carParameters?.models ?? [] {
            if let generations = model.generation {
                for gen in generations {
                    gens.append("\(gen.ext)")
                }
            }
        }
        
        let values : [Any?] = [
            filter.filterCar.carParameters?.marka?.ext,
            filter.filterCar.carParameters?.models.map { "\($0.ext)" }.joined(separator: ","),
            gens.joined(separator: ","),
            filter.filterOptional.yearFrom,
            filter.filterOptional.yearTo,
            filter.filterOptional.priceFrom,
            filter.filterOptional.priceTo,
            filter.filterOptional.korobka,
            filter.filterOptional.kuzov,
            filter.filterOptional.dvigatel,
            filter.filterOptional.colors,
            filter.filterOptional.privods,
            filter.filterOptional.rule,
            filter.filterChecks.carState,
            filter.filterGeneral.region,
            filter.filterOptional.powerFrom,
            filter.filterOptional.powerTo,
            filter.filterOptional.probegFrom,
            filter.filterOptional.probegTo,
            filter.filterOptional.volumeFrom,
            filter.filterOptional.volumeTo,
            filter.filterChecks.isObmen,
            filter.filterOptional.options_single_fields,
            filter.filterOptional.options_choice_fields,
            filter.filterOptional.options_multiple_fields
        ]

        var parameters: [URLQueryItem] = []
        
        for (i, key) in keys.enumerated() {
            if let value = values[i] {
                if value is Int {
                    parameters.append(URLQueryItem(name: key, value: String(value as! Int)))
                } else if value is String {
                    if !(value as! String).isEmpty {
                        parameters.append(URLQueryItem(name: key, value: (value as! String)))
                    }
                } else if value is Bool {
                    if (value as! Bool) {
                        parameters.append(URLQueryItem(name: key, value: "1"))
                    }
                } else if value is [ModalView.ModalData] {
                    let values = (value as! [ModalView.ModalData]).map {
                        x in "\(String(describing: x.id))"
                    }.joined(separator: ",")
                    parameters.append(URLQueryItem(name: key, value: values))
                } else if value is [City?] {
                    let values = (value as! [City?]).filter {
                        $0 != nil
                    }.map {
                        x in "\(x!.id)"
                    }.joined(separator: ",")
                    parameters.append(URLQueryItem(name: key, value: values))
                }
            }
        }
        
        parameters.append(URLQueryItem(name: "sort_by", value: "\(filter.sortBy)"))
        return parameters
    }
}
